<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <p data-lake-id="ua349005f" id="ua349005f"><br></p>
  <p data-lake-id="uc8853ae4" id="uc8853ae4"><span data-lake-id="u274e6c0e" id="u274e6c0e">先来写一段死锁的程序：</span></p>
  <p data-lake-id="ue6be03f9" id="ue6be03f9"><span data-lake-id="u9468645f" id="u9468645f">​</span><br></p>
  <pre lang="java"><code>
package javaCommand;
/**
 * @author hollis
 */
public class JStackDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread(new DeadLockclass(true));//建立一个线程
        Thread t2 = new Thread(new DeadLockclass(false));//建立另一个线程
        t1.start();//启动一个线程
        t2.start();//启动另一个线程
    }
}
class DeadLockclass implements Runnable {
    public boolean falg;// 控制线程
    DeadLockclass(boolean falg) {
        this.falg = falg;
    }
    public void run() {
        /**
         * 如果falg的值为true则调用t1线程
         */
        if (falg) {
            while (true) {
                synchronized (Suo.o1) {
                    System.out.println("o1 " + Thread.currentThread().getName());
                    synchronized (Suo.o2) {
                        System.out.println("o2 " + Thread.currentThread().getName());
                    }
                }
            }
        }
        /**
         * 如果falg的值为false则调用t2线程
         */
        else {
            while (true) {
                synchronized (Suo.o2) {
                    System.out.println("o2 " + Thread.currentThread().getName());
                    synchronized (Suo.o1) {
                        System.out.println("o1 " + Thread.currentThread().getName());
                    }
                }
            }
        }
    }
}

class Suo {
    static Object o1 = new Object();
    static Object o2 = new Object();
}
</code></pre>
  <p data-lake-id="u1e0b0511" id="u1e0b0511"><br></p>
  <p data-lake-id="ua53e3e36" id="ua53e3e36" style="text-align: justify"><span data-lake-id="uc2e15d83" id="uc2e15d83" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">当我启动该程序时，我们看一下控制台：</span></p>
  <p data-lake-id="uf04d0ed4" id="uf04d0ed4" style="text-align: justify"><br></p>
  <p data-lake-id="u79ee3c23" id="u79ee3c23"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1694948245009-c9d0bf3a-db0a-4c78-8ff0-afd4e114c2fe.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_11%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="uc137e6a8" id="uc137e6a8"><br></p>
  <p data-lake-id="uf77cd156" id="uf77cd156"><span data-lake-id="uc0f02515" id="uc0f02515">我们发现，程序只输出了两行内容，然后程序就不再打印其它的东西了，但是程序并没有停止。</span></p>
  <p data-lake-id="ub31e54b4" id="ub31e54b4"><span data-lake-id="u13d18574" id="u13d18574">​</span><br></p>
  <p data-lake-id="u83ea6f1d" id="u83ea6f1d"><span data-lake-id="ue85c626d" id="ue85c626d">这样就产生了死锁。 当线程1使用synchronized锁住了o1的同时，线程2也是用synchronized锁住了o2。当两个线程都执行完第一个打印任务的时候，线程1想锁住o2，线程2想锁住o1。但是，线程1当前锁着o1，线程2锁着o2。所以两个想成都无法继续执行下去，就造成了死锁。</span></p>
  <p data-lake-id="u668089b5" id="u668089b5"><span data-lake-id="u8c83ca71" id="u8c83ca71">​</span><br></p>
  <p data-lake-id="u311611a5" id="u311611a5"><span data-lake-id="udd840b77" id="udd840b77">然后，我们使用jstack来看一下线程堆栈信息：</span></p>
  <p data-lake-id="u65d30ca8" id="u65d30ca8"><span data-lake-id="u8119ec3d" id="u8119ec3d">​</span><br></p>
  <pre lang="java"><code>
Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f0134003ae8 (object 0x00000007d6aa2c98, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007f0134006168 (object 0x00000007d6aa2ca8, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
    at javaCommand.DeadLockclass.run(JStackDemo.java:40)
    - waiting to lock &lt;0x00000007d6aa2c98&gt; (a java.lang.Object)
    - locked &lt;0x00000007d6aa2ca8&gt; (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)
"Thread-0":
    at javaCommand.DeadLockclass.run(JStackDemo.java:27)
    - waiting to lock &lt;0x00000007d6aa2ca8&gt; (a java.lang.Object)
    - locked &lt;0x00000007d6aa2c98&gt; (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.
</code></pre>
  <p data-lake-id="u2059b46a" id="u2059b46a"><br></p>
  <p data-lake-id="u994579b9" id="u994579b9"><span data-lake-id="uce56e8ee" id="uce56e8ee">哈哈，堆栈写的很明显，它告诉我们 Found one Java-level deadlock，然后指出造成死锁的两个线程的内容。然后，又通过 Java stack information for the threads listed above来显示更详细的死锁的信息。 他说</span></p>
  <p data-lake-id="u151c5daf" id="u151c5daf"><span data-lake-id="u2eb8a968" id="u2eb8a968">​</span><br></p>
  <blockquote data-lake-id="ub015d1b7" id="ub015d1b7">
   <p data-lake-id="ue45858fe" id="ue45858fe"><span data-lake-id="u3e66f4f0" id="u3e66f4f0">Thread-1在想要执行第40行的时候，当前锁住了资源&lt;0x00000007d6aa2ca8&gt;,但是他在等待资源&lt;0x00000007d6aa2c98&gt; Thread-0在想要执行第27行的时候，当前锁住了资源&lt;0x00000007d6aa2c98&gt;,但是他在等待资源&lt;0x00000007d6aa2ca8&gt; 由于这两个线程都持有资源，并且都需要对方的资源，所以造成了死锁。 原因我们找到了，就可以具体问题具体分析，解决这个死锁了。</span></p>
  </blockquote>
 </body>
</html>